package p33_HandlerMapper和HandlerAdapter其1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.Controller;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 自定义处理器映射器
 *      请求/c1进来，会找到一个名为c1的控制器bean，然后调用该控制器里的方法，作为控制器处理方法
 */
public class MyHandlerMapping implements HandlerMapping {

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, Controller> mappingCache;

    /**
     * 处理器映射器肯定是初始化时，就得到所有的处理器handler(处理请求的具体代码，跟前面的控制器方法类型)，然后缓存起来，不可能说用的时候才去找处理器
     */
    @PostConstruct
    public void init() {
        Map<String, Controller> beans = applicationContext.getBeansOfType(Controller.class);
        mappingCache = beans.entrySet().stream()
                .filter(i -> i.getKey().startsWith("/"))
                .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
        System.out.println("成功解析:" + mappingCache);
    }

    @Override
    public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        //根据请求对象找到对应的控制器bean
        Controller controller = mappingCache.get(request.getRequestURI());
        if (controller == null) {
            //返回null表示没找到,页面会显示404
            return null;
        }
        //将控制器封装成调用链，因为可能有拦截器
        return new HandlerExecutionChain(controller);
    }
}
